#include <vector>
#include <stdarg.h>
using namespace std;
namespace fsm{

typedef int FSM_SCODE;
typedef int(* FSM_ACTION)(int argc , char ** argv );

typedef vector< FSM_SCODE > FSM_SCODE_MAP;

class CFsmStat{
public:
	FSM_SCODE m_current;
//	FSM_SCODE_MAP m_parent;
	FSM_SCODE_MAP m_children;
public:
	FSM_ACTION trigger;
};

CFsmStat * BuildCFsmStat( FSM_SCODE curr , FSM_ACTION trigger , ... ){
	CFsmStat * PfsmStat = new CFsmStat();
	PfsmStat->m_current = curr;
	PfsmStat->trigger = trigger;
	va_list args;
	va_start(args, trigger);
	while (1){
		FSM_SCODE sCode = va_arg( args, FSM_SCODE );
		if( sCode == -1 ){
			break;
		}
		PfsmStat->m_children.push_back( sCode );
	}
	va_end(args);
	return PfsmStat;
}
typedef vector<CFsmStat * > FSM_STATE_MAP;

class CFsm{
public:
	CFsm(){}
	CFsm( FSM_SCODE begin , FSM_SCODE end  , FSM_STATE_MAP statemap){
		m_begin_code = begin;
		m_end_code = end;
		m_curr_code = m_begin_code;
		m_statemap = statemap;
	}

public:
	FSM_SCODE m_begin_code;
	CFsmStat * m_begin;

	FSM_SCODE m_end_code;
	CFsmStat * m_end;

	FSM_SCODE m_curr_code;
	CFsmStat * m_curr;

	FSM_STATE_MAP m_statemap;
public:
	int trigger( const char * data ){
		if(m_curr){
			m_curr_code = m_curr->trigger( data[0] , NULL );
			
		}else{
			cout << "m_curr is NULL "<<endl;
		}
		return findStat( m_curr_code );
	}
	
	bool findStat( FSM_SCODE scode ){
		FSM_STATE_MAP::iterator iter;
		for( iter = m_statemap.begin();
			iter != m_statemap.end();
			iter++  ){
			if( (*iter)->m_current == scode ){
				m_curr = *iter;
				break;
			}	
		}
		if( iter == m_statemap.end() ){
			m_curr = NULL;
		}
		return true;
	} 
};
CFsm * BuildCFsm( FSM_SCODE begin , FSM_SCODE end , ... ){
	CFsm * fsm_p = new CFsm();
	fsm_p->m_begin_code = begin;
	fsm_p->m_end_code = end;
	fsm_p->m_curr_code = begin;

	va_list args;
	va_start(args, end);
	while (1){
		CFsmStat * fsmStat_p = va_arg( args, CFsmStat* );
		if( fsmStat_p == NULL ){
			break;
		}
		fsm_p->m_statemap.push_back( fsmStat_p );
	}
	va_end(args);
	fsm_p->findStat( begin );
	return fsm_p;
}
}
